home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / bipl.zip / PROGS.ZIP / EMPG.ICN < prev    next >
Text File  |  1992-09-28  |  8KB  |  211 lines

  1. ############################################################################
  2. #
  3. #    File:     empg.icn
  4. #
  5. #    Subject:  Program to produce expression-benchmark program
  6. #
  7. #    Author:   Ralph E. Griswold
  8. #
  9. #    Date:     September 20, 1991
  10. #
  11. ###########################################################################
  12. #
  13. #     This program reads Icon expressions, one per line, and writes out
  14. #  an Icon program, which when run, times the expressions and reports
  15. #  average evaluation time and storage allocation.
  16. #
  17. #     Lines beginning with a # are treated as comments and written to the
  18. #  output program so as to be written as comments when the output program is
  19. #  run.
  20. #
  21. #     Lines beginning with a : are passed to the output program to be
  22. #  evaluated, but not timed.
  23. #
  24. #     Lines beginning with a $ are included at the end of the output
  25. #  program as declarations.
  26. #
  27. #     All other lines are timed in loops.
  28. #
  29. #     An example of input is:
  30. #
  31. #    :T := table(0)
  32. #    $record complex(r,i)
  33. #    T[1]
  34. #    complex(0.0,0.0)
  35. #
  36. #     The resulting output program evaluates the expressions on the last two
  37. #  lines and reports their average time and storage allocation.
  38. #
  39. #     The input file is specified on the command line. The output file
  40. #  is written to a file of the same base name, but with the suffix .icn.
  41. #  For example.
  42. #
  43. #    iconx empg foo.exp
  44. #
  45. #  reads input from foo.exp and writes output to foo.icn.
  46. #
  47. #     This program can be configured to produce output to run under either the
  48. #  Icon interpreter or the Icon compiler. Some defaults differ for the two
  49. #  cases.
  50. #
  51. #     The options are:
  52. #
  53. #    -c    configure for the compiler
  54. #
  55. #    -f s    flags for the executing program (only useful with -x
  56. #        option below)
  57. #
  58. #    -i    configure for the interpreter (the default)
  59. #
  60. #    -o n    number of iterations for computing loop overhead; the default
  61. #          for the interpreter is 10000, for the compiler 1000000
  62. #
  63. #    -t n    number of iterations for timing expressions; the default
  64. #          for the interpreter is 10000, for the compiler 100000
  65. #
  66. #    -x    run the output program
  67. #
  68. #  The number of iterations for timing can be overridden on the command
  69. #  line when the output program is run. For example, in
  70. #
  71. #    icont test
  72. #    iconx test 5000
  73. #
  74. #  the expressions in test.icn are timed using 5000 iterations.
  75. #
  76. #     If a garbage collection occurs during timing, the average time is
  77. #  likely to be significantly distorted and average allocation cannot be
  78. #  computed.  In this case, the number of garbage collections is reported
  79. #  instead.  To avoid misleading results as a consequence, measurement
  80. #  programs should be run with Icon's region sizes set to as large values
  81. #  as possible. To avoid residual effects of one timed expression on
  82. #  another, expressions that allocate significant amounts of storage
  83. #  should be measured in separate programs.
  84. #
  85. #     The number of iterations used to compute loop overhead im empg
  86. #  and the number of iterations used to time expressions in measurement
  87. #  programs should be chosen so that the effects of low clock resolution
  88. #  are minimized.  In particular, systems with very fast CPUs but
  89. #  low clock resolution (like 386 and 486 processors running under
  90. #  MS-DOS) need large values.
  91. #
  92. ############################################################################
  93. #
  94. #  Links: options
  95. #
  96. #  Links: numbers (in the output program, not in empg.icn)
  97. #
  98. ############################################################################
  99.  
  100. link options
  101.  
  102. procedure main(argl)
  103.    local i, decls, line, input, output, opts, processor, over, timing, run
  104.    local name, flags
  105.  
  106.    opts := options(argl,"if:co+t+x")
  107.    processor := \opts["c"]             # if interpreter, null
  108.    flags := (\opts["f"] | "")             # flags for command line
  109.    if \opts["i"] then processor := &null    # interpreter overrides
  110.    over := \opts["o"]
  111.    /over := if /processor then 10000 else 1000000
  112.    timing := \opts["t"]
  113.    /timing := if /processor then 10000 else 100000
  114.    run := opts["x"]                # don't run if null
  115.  
  116.    input := open(name := argl[1]) | stop("*** cannot open input file ***")
  117.    name ?:= {
  118.       tab(upto('.') | 0)
  119.       }
  120.    output := open(name || ".icn","w") | stop("*** cannot open output file ***")
  121.  
  122.    decls := []                    # list for declarations
  123.    write(output,"link numbers")
  124.    write(output,"global _Count, _Coll, _Store, _Overhead, _Names")
  125.    write(output,"procedure main(argl)")
  126.    write(output,"   local _Iter, _T, _S, _Itime, _I")
  127.    write(output,"   _Iter := argl[1] | ",timing)
  128.    write(output,"   _Names := [\"static\",\"string\",\"block \"]")
  129.    write(output,"   write(\"iterations: \",_Iter)")
  130.    write(output,"   write(\"&version: \",&version)")
  131.    write(output,"   write(\"&host: \",&host)")
  132.    write(output,"   write(\"&dateline: \",&dateline)")
  133.    write(output,"   write(\"region sizes: \")")
  134.    write(output,"   _I := 1")
  135.    write(output,"   every _S := ®ions do {")
  136.    write(output,"      write(\"   \",_Names[_I],\"   \",_S)")
  137.    write(output,"      _I +:= 1")
  138.    write(output,"      }")
  139.    write(output,"   _Count := ",over)
  140.    write(output,"   _Itime := &time")
  141.    write(output,"   every 1 to _Count do { &null }")
  142.    write(output,"   _Overhead := real(&time - _Itime) / _Count")
  143.    if /processor then {            # interpreter overhead
  144.       write(output,"   _Itime := &time")
  145.       write(output,"   every 1 to _Count do { &null & &null }")
  146.       write(output,"   _Overhead := real(&time - _Itime) / _Count - _Overhead")
  147.       }
  148.    write(output,"   _Count := _Iter")
  149.    while line := read(input) do 
  150.       case line[1] of {
  151.          ":": {            # evaluate but do not time
  152.             write(output,"   ",line[2:0])
  153.             write(output,"   write(",image(line[2:0]),")")
  154.             }
  155.          "$": {            # line of declaration
  156.             put(decls,line[2:0])
  157.             write(output,"   write(",image(line[2:0]),")")
  158.             }
  159.          "#":            # comment
  160.             write(output,"   write(",image(line),")")
  161.          default: {        # time in a loop
  162.             write(output,"   write(",image(line),")")
  163.             write(output,"   _Prologue()")
  164.             write(output,"   _Itime := &time")
  165.             write(output,"   every 1 to _Count do {")
  166.             write(output,"      &null & ", line)
  167.             write(output,"      }")
  168.             write(output,"   _Epilogue(&time - _Itime)")
  169.             }
  170.       }
  171.    write(output,"end")
  172.    write(output,"procedure _Prologue()")
  173.    write(output,"   _Store := []")
  174.    write(output,"   _Coll := []")
  175.    write(output,"   collect()")
  176.    write(output,"   every put(_Store,&storage)")
  177.    write(output,"   every put(_Coll,&collections)")
  178.    write(output,"end")
  179.    write(output,"procedure _Epilogue(_Time)")
  180.    write(output,"   local _I")
  181.    write(output,"   every put(_Store,&storage)")
  182.    write(output,"   every put(_Coll,&collections)")
  183.    write(output,"   write(fix(real(_Time) / _Count - _Overhead,1,8,5),\" ms.\")")
  184.    write(output,"   if _Coll[1] = _Coll[5] then {")
  185.    write(output,"      write(\"average allocation:\",)")
  186.    write(output,"         every _I := 1 to 3 do")
  187.    write(output,"            write(\"   \",_Names[_I],fix(real(_Store[_I + 3] - _Store[_I]),_Count,12,5))")
  188.    write(output,"      }")
  189.    write(output,"   else {")
  190.    write(output,"   write(\"garbage collections:\")")
  191.    write(output,"   write(\"   total \",right(_Coll[5] - _Coll[1],4))")
  192.    write(output,"   every _I := 6 to 8 do write(\"   \",_Names[_I - 5],right(_Coll[_I] - _Coll[_I - 4],4))")
  193.    write(output,"   write(\"region sizes: \")")
  194.    write(output,"   _I := 1")
  195.    write(output,"   every _S := ®ions do {")
  196.    write(output,"      write(\"   \",_Names[_I],\"   \",_S)")
  197.    write(output,"      _I +:= 1")
  198.    write(output,"      }")
  199.    write(output,"      }")
  200.    write(output,"   write()")
  201.    write(output,"end")
  202.    every write(output,!decls)        # write out declarations
  203.  
  204.    if \run then {
  205.       if \processor then system("iconc -s "|| flags || " " || name)
  206.       else system("icont -s " || flags || " " || name)
  207.       system(name)
  208.       }
  209.  
  210. end
  211.